<?php

namespace App\Services;

use App\Enums\OrderPay;
use App\Enums\PayMethod;
use App\Exceptions\InvalidRequestException;
use App\Jobs\OrderPayExpiredTimeJob;
use App\Models\Material;
use App\Models\Message;
use App\Models\Order;
use App\Models\Project;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Yansongda\Pay\Exception\ContainerException;
use Yansongda\Pay\Exception\InvalidParamsException;
use Yansongda\Pay\Exception\ServiceNotFoundException;
use Yansongda\Pay\Pay;
use Illuminate\Http\Response;

class OrderService
{


    /**
     * 下单购买
     * @param int $project_id
     * @param User $user
     * @param int $pay_method
     * @return mixed
     */
    public function buy(int $project_id, User $user, int $pay_method): mixed
    {
        return DB::transaction(function () use ($project_id, $user, $pay_method) {
            //判断当前项目是否满足购买条件
            $project = Project::query()->show()->where('id', $project_id)->first();
            if (!$project) {
                throw new InvalidRequestException('项目不存在');
            }
            //判断用户是否有此项目未支付切未过期的订单
            if (Order::query()->where('user_id', $user->id)
                ->where('project_id', $project_id)
                ->where('pay', false)
                ->where('pay_expired_time', '>=', now())
                ->exists()) {
                throw new InvalidRequestException('存在未支付的订单，请前往购买记录支付');
            }
            //判断当前用户是否购买过
            if (Order::query()->where('project_id', $project_id)->where('user_id', $user->id)->where('pay', true)->exists()) {
                throw new InvalidRequestException('不允许重复购买');
            }
            //判断当前产品否超出购买限制
            if (Order::query()->where('project_id', $project_id)->where('pay', true)->count() >= $project->total) {
                throw new InvalidRequestException('当前项目不允许下单购买');
            }
//            //判断项目资料是否还有剩余数量
//            if (Material::query()->where('project_id', $project_id)->where('buy', false)->count()) {
//                throw new InvalidRequestException('资料不足，无法购买');
//            }
//            $material = Material::where('project_id', $project_id)->lockForUpdate()->where('buy', false)->inRandomOrder()->first();
//            $material->buy = true;
//            $material->save();
            //创建订单数据
            $order = Order::query()->create([
                'user_id' => $user->id,
                'project_id' => $project_id,
                'material_id' => 0,
                'pay_method' => $pay_method,
                'money' => $project->price,
                'order_no' => onlyOrderSn(),
                'pay_expired_time' => now()->addMinutes(10),
                'project_info' => json_encode([
                    'category' => $project->category->name,
                    'title' => $project->title,
                    'image' => $project->image,
                    'describe' => $project->describe,
                    'date' => $project->date,
                    'address' => getAreaName($project->province_id) . getAreaName($project->city_id),// . getAreaName($project->district_id),
                    'price' => $project->price
                ]),
            ]);
            //调用支付
            app(PayService::class)->scan($order);
            OrderPayExpiredTimeJob::dispatch($order->id)->delay($order->pay_expired_time)->afterCommit();
            return $order;
        }, 2);
        //调用支付
    }


    /**
     * 订单过期
     * @param int $order_id
     */
    public function expired(int $order_id)
    {
        DB::transaction(function () use ($order_id) {
            $order = Order::query()->where('id', $order_id)->first();
            if (!$order->pay) {
                $order->pay = OrderPay::EXPIRED;
//                $material = $order->material;
//                $material->buy = false;
//                $material->save();
                $order->save();
            }
        });
    }


    //支付成功
    public function paySuccess(string $order_no, string $trade_no, string $pay_time, array $response)
    {
        DB::transaction(function () use ($order_no, $trade_no, $pay_time, $response) {
            $order = Order::query()->where('order_no', $order_no)
                ->first();
            if ($order->pay == OrderPay::PAID) {
                return;
            }
            $order->pay = OrderPay::PAID;
            $order->trade_no = $trade_no;
            $order->pay_time = $pay_time;
            $order->pay_response = json_encode($response, JSON_UNESCAPED_UNICODE);
            $order->save();
//            $material = $order->material;
//            if (!$material->buy) {
//                $material->buy = true;
//                $material->save();
//            }
            //添加我的消息
            Message::query()->create([
                'user_id' => $order->user_id,
                'content' => '购买成功' . $order->project->title . '文件资料',
            ]);
            //产品增加销量
            $project = $order->project;
            $project->number = $project->number + 1;
            $project->save();
        }, 2);
    }


    //分配资料
    public function allocationMaterial(Order $order)
    {
        return DB::transaction(function () use ($order) {
            if (!Material::query()->where('project_id', $order->project_id)->where('buy', false)->count()) {
                throw new InvalidRequestException(ConfigService::all()->where('name', 'material_inadequate')->value('content'), Response::HTTP_CREATED);
            }
            $material = Material::where('project_id', $order->project_id)->lockForUpdate()->where('buy', false)->inRandomOrder()->first();
            $material->buy = true;
            $material->save();
            $order->material_id = $material->id;
            $order->save();
            return $order;
        });

    }
}
